/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <nlohmann/json.hpp>

#include <ipc_skeleton.h>
#include <smart_serve_log.h>
#include <smart_serve_service.h>

#include <service/service.h>
#include <llamacpp/plugin.h>

namespace OHOS {
namespace SmartServe {

using json = nlohmann::json;

void SmartServeService::OnStart()
{
    SMART_SERVE_LOGI("SmartServeService ::OnStart.");
    if (!Service::Init()) {
        SMART_SERVE_LOGI("Failed to init server for smart service.");
    }

    if (!llamacpp::Init()) {
        SMART_SERVE_LOGI("Failed to init llamacpp for smart service.");
    }
}

void SmartServeService::OnStop()
{
    SMART_SERVE_LOGI("SmartServeService ::OnStop.");
    llamacpp::Finalize();
    Service::Finalize();
}

template<typename Object>
std::string Dump(const Object& obj)
{
    return json(obj).dump();
}

std::string MakeLLMRequest(const std::string& request)
{
    try {
        json data = json::parse(request);
        if (!data.contains("id")) {
            return Dump(SmartServe::Request{
                .type = SmartServe::Request::EVAL_LLM,
                .pid = OHOS::IPCSkeleton::GetCallingPid(),
                .request =
                    SmartServe::EvalLLMRequest{
                        .model = data["model"],
                        .input = data["input"],
                    },
                });
        } else {
            return Dump(SmartServe::Request{
                .type = SmartServe::Request::GET_LLM_RESULT,
                .pid = OHOS::IPCSkeleton::GetCallingPid(),
                .request =
                    SmartServe::GetLLMResultRequest{
                        .id = data["id"],
                    },
                });
        }
    } catch(const json::parse_error& e) {
        SMART_SERVE_LOGI("Invalid request: %s.", request.c_str());
    }

    return "";
}

ErrCode SmartServeService::Serve(const std::string &request, std::string &response)
{
    SMART_SERVE_LOGI("Serve request: %s.", request.c_str());
    response = Service::Instance()->Serve(MakeLLMRequest(request));
    SMART_SERVE_LOGI("Serve response: %s.", response.c_str());
    return ERR_OK;
}

} // namespace SmartServe
} // namespace OHOS
